<template>
  <div class="root-box">
    <van-field
      ref="scanDom"
      v-model="scan"
      left-icon="scan"
      :placeholder="propPlaceholder"
      size="small"
      clearable
      border
      @keyup="handleScanOver"
      @clear="focus"
      :disabled="disabled && disabled == true ? true : false"
      class="field"
      clickable
    >
      <template #button v-if="showBtn">
        <van-button type="info" @click="btnClick" style="height: 25px;">
          <slot name="btn"></slot>
        </van-button>
      </template>
    </van-field>
  </div>
</template>
<script>
import barcodeParse from '@/util/barcodeParse.js'
/**
   * @Description： 通用扫描组件
   1、扫描成功或者失败清除并聚焦输入框
   2、成功或者失败分别给出成功或者失败的提示音
   3、支持rfid/sn/系统编号规则(目前仅判断编码段1表达式类型是自定义字符串的编号规则)
   4、格式校验成功，提示【扫描结束，处理中】，格式校验失败，提示【propErrorMsg】
   5、格式没有问题，回调 this.$emit('scanCall', '扫描结果'), 扫描结果已经使用strings.trimrl剔除前后空格

   常见问题：
   * @Author wyt
   * @Date 2021/8/23
   */
export default {
  title: '扫描组件',
  name: 'FortenScan',
  /**
     * @param  propPlaceholder  【必须】，扫描框占位符： 如: 请扫描标签拣货/取消拣货
     * @param  propErrorMsg     【必须】，格式解析失败后提示信息，如： 请扫描RFID/SN
     * @param  propTypeArr      扫描类型 rfid,sn,等，可以传数组，也可以传编号规则代码,如：purchase_order_key 采购订单的编号规则代码，目前仅判断 编码段1表达式类型是 自定义字符串
     * @param  propTypeFun      自定义方法校验，return true 校验通过如：  :propTypeFun="(scan)=> {return scan.toLowerCase().startsWith('po') || scan.toLowerCase().startsWith('an')  || scan.toLowerCase().startsWith('asn')}"
     * @param  disabled         true: 禁用扫描框
     * @param  noAutoFocus      true: 不自动聚焦，即控件创建后不自动聚焦，只用于一个页面有多个控件
     */
  props: {
    propPlaceholder: String,
    propErrorMsg: String,
    propTypeArr: Array,
    propTypeFun: Object,
    disabled: Boolean,
    noAutoFocus: Boolean,
    showBtn: {type: Boolean, default: false}
  },
  data() {
    return {
      //扫描结果
      scan: '',

      //系统编号规则
      serialRuleList: [],

      //错误提示
      errorMsg: ''
    }
  },
  mounted() {
    this.getSerialRule()
  },
  created() {
    if (!this.noAutoFocus) {
      this.focus(true)
    }
    // this.bindWindow()
    console.log(this)
  },

  methods: {
    //获取编号规则列表
    getSerialRule() {
      this.$ajax.get('/sys/serial_rule/list').then(resp => {
        if (resp.code == 0 && resp.data) {
          this.serialRuleList =  resp.data
        }
      })
    },

    //清除并聚焦
    focus(isByInit) {
      this.bindWindow()
      if (isByInit) {  //实例后调用，延迟
        setTimeout(() => {
          this.scan = ''
          this.$refs.scanDom.focus()
        }, 500)
      } else { //其他，不延迟
        this.scan = ''
        this.$refs.scanDom.focus()
      }
    },

    //扫描
    handleScanOver(event) {
      if (event && !(event.keyCode == '13')) {
        return
      }
      if (!this.propPlaceholder || !this.propErrorMsg) {
        this.$notify.error('缺少参数propPlaceholder或propErrorMsg')
        this.focus()
        return
      }
      this.errorMsg = this.propErrorMsg

      //获取PDA扫描结果
      if (window.isPDAScan()) this.scan = window.getPDAScan()
      // eslint-disable-next-line no-alert
      this.scan = this.strings.trimrl(this.scan)

      console.log('FortenScan.scan', this.scan)

      if (this.strings.isBlank(this.scan)) {
        this.$notify.warning('请扫描')
        this.focus()
        window.scanError()
        return
      }

      let isError = true
      if (this.propTypeArr && this.propTypeArr.length > 0) {
        this.propTypeArr.forEach(propType => {
          switch (propType) {
            case 'rfid':  //rfid
              if (barcodeParse.barCodeType(this.scan) == 'RFID') {
                isError = false
              } else {
                this.errorMsg += '\nRFID以F开头'
              }
              break
            case 'sn': //sn
              if (barcodeParse.barCodeType(this.scan) == 'SN') {
                isError = false
              } else {
                this.errorMsg += '\nSN以SN开头'
              }
              break
            case 'GTIN': //GTIN
              if (barcodeParse.barCodeType(this.scan) == 'GTIN') {
                isError = false
              }
              break
            default: //默认为系统编号
              if (this.serialRuleList.length < 1) { //没有编号列表，直接忽略
                isError = false
              } else {
                let findIndex = this.serialRuleList.findIndex(ob => ob.code == propType)
                if (findIndex == -1) { //未找到也跳过
                  isError = false
                } else {
                  let rule = this.serialRuleList[findIndex]
                  if (rule.part1Cond == 'string_') {  //编码段1表达式类型是 自定义字符串
                    if (this.scan.toLowerCase().startsWith(rule.part1.toLowerCase())) {
                      isError = false
                    } else {
                      this.errorMsg += '\n当前配置' + rule.name + '的编号规则以' + rule.part1 + '开头'
                    }
                  } else {
                    isError = false
                  }
                }
              }
          }
        })
      } else if (this.propTypeFun) {  //方法校验
        console.log('666', this.propTypeFun)
        isError = !this.propTypeFun(this.scan)
      } else { //无任何校验时，只要有数据就正常
        isError = false
      }

      let scanOld = this.scan
      this.focus()

      //校验失败
      if (isError) {
        //失败提示音
        window.scanError()
        this.$notify.warning({
          message: '条码：' + scanOld + '\n' + this.errorMsg,
          onClick: () => {
            this.$notify.clear()
          }
        })
      } else {
        //成功提示音 PDA扫描后本身就有提示音，
        // window.scanOk()
        // this.$notify({
        //   message: '扫描结束，处理中',
        //   color: '#67c23a',
        //   background: '#f0f9eb',
        // })
        this.$emit('scanCall', scanOld)
      }
    },
    //按钮点击事件
    btnClick() {
      this.$emit('btnClick', this.scan)
    },
    //绑定window对象
    bindWindow() {
      window.fortenScan =  (code) => {
        // eslint-disable-next-line no-alert
        this.handleScanOver(null)
      }
    }
  }
}
</script>

<style scoped lang="scss">
  .root-box{
    /deep/ .field {
      .van-icon-scan {
        font-size: 17px;
        z-index: 999;
        position: absolute;
        left: 30%;
        top: 7px;
      }

      input {
        background:hsla(0,0%,100%,.9);
        border: 1px solid #444;
        border-bottom: 0px;
        border-radius: 5px;
        box-shadow: 0 2px 0 #000;
        color: #323233;
        display: block;
        float: left;
        font-size: 12px;
        font-weight: 400;
        height: 25px;
        margin: 0 0 2px 0;
        padding: 10px 15px 5px 35%;
      }


      :-moz-placeholder {
        color: #646566;
        font-style:italic
      }

      ::-moz-placeholder {
        color: #646566;
        font-style:italic
      }

      ::-webkit-input-placeholder {
        color: #646566;
        font-style:italic
      }

      :-ms-input-placeholder {
        color: #646566;
        font-style:italic
      }

      input:focus {
        -webkit-animation: glow 800ms ease-out infinite alternate;
        -moz-animation: glow 800ms ease-out infinite alternate;
        -o-animation: glow 800ms ease-out infinite alternate;
        -ms-animation: glow 800ms ease-out infinite alternate;
        animation: glow 800ms ease-out infinite alternate;
        border-color: #393;
        box-shadow: 0 0 5px rgba(7, 193, 96,.2), inset 0 0 5px rgba(7, 193, 96,.1), 0 2px 0 #000;
        outline: none;
      }


      @-webkit-keyframes glow {
        0% {
          border-color: #393;
          box-shadow: 0 0 5px rgba(7,193, 96,.2), inset 0 0 5px rgba(0,255,0,.1), 0 2px 0 #000;
        }
        100% {
          border-color: #6f6;
          box-shadow: 0 0 20px rgba(7, 193, 96,.6), inset 0 0 10px rgba(0,255,0,.4), 0 2px 0 #000;
        }
      }

      @-moz-keyframes glow {
        0% {
          border-color: #393;
          box-shadow: 0 0 5px rgba(7, 193, 96,.2), inset 0 0 5px rgba(0,255,0,.1), 0 2px 0 #000;
        }
        100% {
          border-color: #6f6;
          box-shadow: 0 0 20px rgba(7, 193, 96,.6), inset 0 0 10px rgba(0,255,0,.4), 0 2px 0 #000;
        }
      }

      @-o-keyframes glow {
        0% {
          border-color: #393;
          box-shadow: 0 0 5px rgba(7, 193, 96,.2), inset 0 0 5px rgba(0,255,0,.1), 0 2px 0 #000;
        }
        100% {
          border-color: #6f6;
          box-shadow: 0 0 20px rgba(7, 193, 96,.6), inset 0 0 10px rgba(0,255,0,.4), 0 2px 0 #000;
        }
      }

      @-ms-keyframes glow {
        0% {
          border-color: #393;
          box-shadow: 0 0 5px rgba(7, 193, 96,.2), inset 0 0 5px rgba(0,255,0,.1), 0 2px 0 #000;
        }
        100% {
          border-color: #6f6;
          box-shadow: 0 0 20px rgba(7, 193, 96,.6), inset 0 0 10px rgba(0,255,0,.4), 0 2px 0 #000;
        }
      }

      @keyframes glow {
        0% {
          border-color: #393;
          box-shadow: 0 0 5px rgba(0,255,0,.2), inset 0 0 5px rgba(0,255,0,.1), 0 2px 0 #000;
        }
        100% {
          border-color: #6f6;
          box-shadow: 0 0 20px rgba(0,255,0,.6), inset 0 0 10px rgba(0,255,0,.4), 0 2px 0 #000;
        }
      }

    }
  }
</style>
